package com.sigmatrix.h5.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sigmatrix.h5.dao.DisDealerAcctRegAuditDao;
import com.sigmatrix.h5.dao.DisTerminalShopDao;
import com.sigmatrix.h5.entity.DisDealer;
import com.sigmatrix.h5.entity.DisDealerAcct;
import com.sigmatrix.h5.entity.DisDealerAcctRegAudit;
import com.sigmatrix.h5.entity.DisTerminalShop;
import com.sigmatrix.h5.entity.v2.DisAcctRole;
import com.sigmatrix.h5.entity.v2.DisRole;
import com.sigmatrix.h5.enums.ApplyStatus;
import com.sigmatrix.h5.enums.ApplyType;
import com.sigmatrix.h5.exception.MessageException;
import com.sigmatrix.h5.service.DealerService;
import com.sigmatrix.h5.service.DealerWareHouseService;
import com.sigmatrix.h5.service.DisAcctRoleService;
import com.sigmatrix.h5.service.DisDealerAcctRegAuditService;
import com.sigmatrix.h5.service.DisDealerAcctService;
import com.sigmatrix.h5.service.DisDealerService;
import com.sigmatrix.h5.service.DisRoleResService;
import com.sigmatrix.h5.service.DisRoleService;
import com.sigmatrix.h5.service.DisTerminalShopDetailService;
import com.sigmatrix.h5.service.DisTerminalShopService;
import com.sigmatrix.h5.service.db.DisAcctRoleDBService;
import com.sigmatrix.h5.service.db.DisRoleDBService;
import com.sigmatrix.h5.utils.Assert;
import com.sigmatrix.h5.utils.CommonUtils;
import com.sigmatrix.h5.utils.Constants;
import com.sigmatrix.h5.utils.MD5Utils;
import com.sigmatrix.h5.utils.SessionUtils;
import com.sigmatrix.h5.utils.ThreadPool;
import com.sigmatrix.h5.web.args.DealerAuditParam;
import com.sigmatrix.h5.web.args.DealerRegParam;
import com.sigmatrix.h5.web.args.ShopAuditParam;
import com.sigmatrix.h5.web.mode.AdviceMessage;
import com.sigmatrix.h5.web.mode.DealerRegMode;
import com.sigmatrix.sc.jdbc.common.lang.Page;
import com.sigmatrix.sc.jdbc.common.service.ServiceImpl;
import com.sigmatrix.sc.rabbitmq.lang.RabbitSender;

/**
 * 
 *@ClassName: DisDealerAcctRegAuditServiceImpl
 *@Description: 经销商反向注册审核记录
 *@author MH
 *@date 2017年11月8日 上午9:23:50
 */
@Service
public class DisDealerAcctRegAuditServiceImpl extends ServiceImpl<DisDealerAcctRegAudit, Integer> implements DisDealerAcctRegAuditService{
	Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	private DisDealerAcctRegAuditDao disDealerAcctRegAuditDao;
	
	@Autowired
	private DisDealerService disDealerService;
	
	@Autowired
	private DisDealerAcctService disDealerAcctService;
	
	@Autowired
	private DisRoleService distributionRoleService;
	
	@Autowired
	private DisAcctRoleService distributionAcctRoleService;
	
	@Autowired
	private DisRoleResService distributionRoleResService;
	
	@Autowired
	private DealerService dealerService;
	
	@Autowired
	private DealerWareHouseService dealerWareHouseService;
	
	@Autowired
	private RabbitSender sender;
	
	@Autowired
	private DisTerminalShopDao disTerminalShopDao;
	
	@Autowired
	private DisTerminalShopDetailService disTerminalShopDetailService;
	
	@Autowired
	private DisTerminalShopService disTerminalShopService;
	
	@Autowired
	private DisRoleDBService disRoleService;
	
	@Autowired
	private DisAcctRoleDBService disAcctRoleService;
	
	@Override
	public Page<DealerRegMode> findDealerRegPage(DisDealerAcctRegAudit vo,int pageNo,int pageSize) {
		if(CommonUtils.isEmpty(vo)){
			vo = new DisDealerAcctRegAudit();
		}
		vo.setApplyType(ApplyType.DEALER.value);
		vo.setStatus(ApplyStatus.NO_AUDIT.value);
		Page<DisDealerAcctRegAudit> page = select(vo, pageNo, pageSize);
		if(CommonUtils.isNotEmpty(page)) return page.convert(DealerRegMode.class);
		return null;
	}

	@Override
	@Transactional
	public DealerRegMode regist(DealerRegParam registInfo) {
		//校验非空参数
		assertArgsNotNull(registInfo);
		//1.生成一条经销商记录，状态为停用
		Integer dealerId = disDealerService.saveTempRecord(registInfo);
		//2.生成一条审核记录，状态为未审核
		DisDealerAcctRegAudit audit = new DisDealerAcctRegAudit();
		audit.setApplyType(ApplyType.DEALER.value);
		audit.setContact(registInfo.getCellPhoneNum());
		audit.setDealerName(registInfo.getName());
		audit.setDealerId(dealerId);//保存临时数据主键
		audit.setContact(registInfo.getCellPhoneNum());//联系电话
		audit.setStatus(ApplyStatus.NO_AUDIT.value);//默认未审核
		audit.setName(registInfo.getContactUserName());//联系人
		audit.setOpenId(registInfo.getOpenId());
		audit.setPwd(MD5Utils.getMD5Code(registInfo.getPwd()));
		audit.setApplyTime(new Date());
		audit.setPromotionCode(registInfo.getPromotionCode());
		audit.setPromotionCodeType(registInfo.getPromotionCodeType());
		Integer auditId = insertSelective(audit);
		DealerRegMode mode = new DealerRegMode();
		BeanUtils.copyProperties(audit, mode);
		mode.setId(auditId);
		return mode;
	}
	
	/**
	 * 
	 *@Title: assertArgsNotNull
	 *@Description:校验注册非空参数 
	 *@return void
	 *@author MH
	 *@date 2017年11月10日 下午5:10:52
	 *@param registInfo
	 */
	private void assertArgsNotNull(DealerRegParam registInfo){
		Assert.notNull(registInfo.getName(), "经销商名称不能为空");
		Assert.notNull(registInfo.getContactUserName(), "联系人姓名不能为空");
		Assert.notNull(registInfo.getCellPhoneNum(), "联系电话不能为空");
		Assert.isCellPhoneNumber(registInfo.getCellPhoneNum(), "联系电话不是有效的手机号");
		Assert.notNull(registInfo.getPromotionCode(), "推广码不能为空");
		Assert.notNull(registInfo.getOpenId(), "openId不能为空");
	}

	@Override
	@Transactional
	public void auditDealer(DealerAuditParam param) {
		Assert.notNull(param.getId(), "请选择要审核的记录");
		Assert.notNull(param.getStatus(), "审核状态不能为空");
		/**
		 * 如果同意：
		 * 	1.跟平台同步经销商信息
		 * 	2.生成CRM账号
		 * 	3.修改审核状态
		 */
		DisDealerAcctRegAudit audit = findById(param.getId());
		Assert.notNull(audit, "id不正确");
		if(!ApplyStatus.NO_AUDIT.value.equals(audit.getStatus()))
			throw new MessageException("该记录的状态不是未审核");
		//如果审批通过，就创建CRM账号
		audit.setStatus(param.getStatus());
		DisDealer dealer = disDealerService.findById(audit.getDealerId());
		if(ApplyStatus.AGREE.value.equals(param.getStatus())){
			Assert.notNull(dealer, "审核信息中没有经销商信息");
			//1.生成CRM账号(先生成CRM账号再跟平台同步，平台同步以后不能回滚)
			DisDealerAcct acct = disDealerAcctService.save(audit, dealer);
			//2.跟平台同步经销商信息
			disDealerService.synDealer(audit,dealer);
			//3.创建权限信息
			ThreadPool.submit(Void ->{
				genRoleInfoV2(acct.getId());//生成CRM账号
				dealerWareHouseService.createDeafultWareHouse(dealer);//设置默认仓库
				sender.send(0,new AdviceMessage(dealer.getCellPhoneNum(), SessionUtils.getEseCode(),acct.getPromotionCode()));//发短信
				});
			//同步到企业表
			dealerService.copyOfDis(dealer);
			
		}else if(ApplyStatus.REJECT.value.equals(param.getStatus())){
			//如果审核不同意，就状态改为删除
			dealer.setStatus(Constants.STATUS_DELETE);
			disDealerService.updateSelective(dealer);
		}
		audit.setReason(param.getReason());
		updateSelective(audit);
	}
	//权限变更，全新的权限
	@Transactional
	private void genRoleInfoV2(Integer acctId) {
		/**
		 * 
		 * 	CRM账号表：_distribution_dealers_acct
			CRM角色表：distribution_role
			CRM账号角色关系表:distribution_acct_role
		 * 
		 */
		//1：查询distribution_role    admin权限的id
		DisRole disRoleAdmin=disRoleService.findAdmin();
		Assert.notNull(disRoleAdmin, "管理员角色不存在");
		//2:将admin权限的id赋予distribution_role
		DisAcctRole role = new DisAcctRole();
		role.setAcctId(acctId);
		role.setRoleId(disRoleAdmin.getId());
		disAcctRoleService.insert(role);
	}

	@Transactional
	private void genRoleInfo(Integer dealerId,Integer acctId){
		//创建admin角色
		Integer roleId = distributionRoleService.createAdmin(dealerId);
		Assert.notNull(roleId, "创建角色失败");
		//把账号赋予admin角色
		Integer acctRoleId = distributionAcctRoleService.create(dealerId, acctId, roleId);
		Assert.notNull(acctRoleId, "账号绑定角色失败");
		//给角色授予所有权限
		distributionRoleResService.grantAllRes(dealerId, roleId);
	}
	
	@Override
	public DisDealerAcctRegAudit findLastByOpenId(String openId) {
		DisDealerAcctRegAudit audit = new DisDealerAcctRegAudit();
		audit.setOpenId(openId);
		audit.setApplyType(ApplyType.SHOP.value);
		HashMap<String, String> order = new HashMap<String,String>();
		order.put("applyTime", "desc");
		List<DisDealerAcctRegAudit> list = select(audit,order);
		return CommonUtils.isEmpty(list)?null:list.get(0);
	}
	@Override
	public Page<DisDealerAcctRegAudit> findAuditList(DisDealerAcctRegAudit po, int pageNo, int pageSize) {
		return disDealerAcctRegAuditDao.findAuditList(po,pageNo,pageSize);
	}
	
	@Override
	public void audit(List<ShopAuditParam> vo) {
		Assert.notNull(vo, "请选择要审核的记录");
		for (ShopAuditParam distributionAcctRegAudit : vo) {
			final DisDealerAcctRegAudit po = new DisDealerAcctRegAudit();
			if(CommonUtils.isNotEmpty(vo)) BeanUtils.copyProperties(distributionAcctRegAudit, po);
			audit(po);
		}
	}
	@Override
	@Transactional
	public void audit(DisDealerAcctRegAudit vo){
		//验证ID STATUS是否为空
		Assert.notNull(vo,"审核信息不能为空");
		Assert.notNull(vo.getId(),"请选择要审核的记录");
		Assert.notNull(vo.getStatus(),"请选择要审核的状态");
		//验证记录是否有效
		final DisDealerAcctRegAudit data = findById(vo.getId());
		Assert.notNull(data,"没有查询到审核记录");
		//验证类型是否是门店注册
		switch (data.getApplyType()) {
		case Constants.APPLY_TYPE_STORE:
			data.setStatus(vo.getStatus());
			data.setReason(vo.getReason());
			auditShop(data);
			break;
		case Constants.APPLY_TYPE_DEALER:
			DealerAuditParam param = new DealerAuditParam();
			param.setId(vo.getId());
			param.setReason(vo.getReason());
			param.setStatus(vo.getStatus());
			auditDealer(param);
			break;
		default:
			throw new MessageException("目前不支持该审核类型");
		}
	}
	
	private void auditShop(DisDealerAcctRegAudit data){
		DisDealerAcctRegAudit audit = findById(data.getId());
		Assert.notNull(audit, "id不正确");
		if(!ApplyStatus.NO_AUDIT.value.equals(audit.getStatus()))
			throw new MessageException("该记录的状态不是未审核");
		//如果是同意就把终端门店表里的记录改为有效
		Short shopStatus = null;
		if(ApplyStatus.AGREE.value == data.getStatus()){
			shopStatus = Constants.STATUS_ENABLE;
			disTerminalShopDetailService.copy(data.getAccount(), data);
			//如果密码不为空，则为小程序端反向注册终端门店，此时要添加crm账号
			if(CommonUtils.isNotEmpty(data.getPwd())) {
				createCrm(data);
			}
		}else{
			shopStatus = Constants.STATUS_DELETE;
		}
		disTerminalShopDao.updateStatusByCode(data.getAccount(), shopStatus);
		updateSelective(data);
	}
	private void createCrm(DisDealerAcctRegAudit data) {
		DisDealer dealer = disDealerService.findById(data.getDealerId());
		Assert.notNull(dealer, "经销商信息为空");
		DisTerminalShop shop = disTerminalShopService.findByCode(data.getAccount());
		Assert.notNull(shop, "终端店信息为空");
		Integer acctId = disDealerAcctService.save(data, dealer,shop);
		//3.创建权限信息
		ThreadPool.submit(Void ->{
//			genRoleInfo(dealer.getId(), acctId);//生成CRM账号
			genRoleInfoV2(acctId);//生成CRM账号
			//发短信
//		sender.send(0,new AdviceMessage(dealer.getCellPhoneNum(), SessionUtils.getEseCode(),dealer.getPromotionCode()));
			});
	}

	/**
	 * 
	 *@Title: findRegistShopByAccountAndDealerId
	 *@Description:
	 *@author MH
	 *@date 2018年2月7日 下午4:08:38
	 */
	@Override
	public DisDealerAcctRegAudit findRegistShopByAccountAndDealerId(String account, Integer dealerId) {
		DisDealerAcctRegAudit audit = new DisDealerAcctRegAudit();
		audit.setApplyType(ApplyType.SHOP.value);
		audit.setAccount(account);
		audit.setDealerId(dealerId);
		List<DisDealerAcctRegAudit> list = select(audit);
		return CommonUtils.isEmpty(list)?null:list.get(0);
	}
	/**
	 * 
	 *@Title: submitAgin
	 *@Description:
	 *@author MH
	 *@date 2018年2月7日 下午4:08:34
	 */
	@Override
	public void submitAgin(Integer id, String shopCode) {
		DisDealerAcctRegAudit audit = new DisDealerAcctRegAudit();
		audit.setId(id);
		audit.setStatus(ApplyStatus.NO_AUDIT.value);
		updateSelective(audit);
		disTerminalShopDao.submitAgin(shopCode);
		
	}
	/**
	 * 
	 *@Title: findRegistShopByOpenId
	 *@Description:
	 *@author MH
	 *@date 2018年2月7日 下午4:08:26
	 */
	@Override
	public List<DisDealerAcctRegAudit> findRegistShopByOpenId(String openId) {
		DisDealerAcctRegAudit audit = new DisDealerAcctRegAudit();
		audit.setApplyType(ApplyType.SHOP.value);
		audit.setOpenId(openId);
		return select(audit);
	}

	/**(non-Javadoc)
	 *@Title: auditShop
	 *@Description:
	 *@see com.sigmatrix.h5.service.DisDealerAcctRegAuditService#auditShop(com.sigmatrix.h5.web.args.DealerAuditParam)
	 *@author wjwei
	 *@date 2018年3月6日 下午2:40:10
	 */
	@Override
	public void auditShop(ShopAuditParam param) {
		final DisDealerAcctRegAudit po = new DisDealerAcctRegAudit();
		if(CommonUtils.isNotEmpty(param)) BeanUtils.copyProperties(param, po);
		audit(po);
	}

	/**(non-Javadoc)
	 *@Title: validateAudit
	 *@Description:
	 *@see com.sigmatrix.h5.service.DisDealerAcctRegAuditService#validateAudit(java.lang.String)
	 *@author wjwei
	 *@date 2018年3月8日 上午10:28:36
	 */
	@Override
	public void validateAudit(String loginName) {
		DisDealerAcctRegAudit audit = new DisDealerAcctRegAudit();
		audit.setAccount(loginName);
		audit.setStatus(ApplyStatus.NO_AUDIT.value);
		if(disDealerAcctRegAuditDao.selectCount(audit)>0) {
			throw new MessageException("手机号："+loginName+"，还未审核完成");
		}
		audit.setStatus(ApplyStatus.REJECT.value);
		if(disDealerAcctRegAuditDao.selectCount(audit)>0) {
			throw new MessageException("手机号："+loginName+"，审核驳回，请重新审核");
		}
	}
}
